1
2
3
4 package uk.ac.roe.antigen.ant;
5
6 import java.io.BufferedInputStream;
7 import java.io.File;
8 import java.io.FileOutputStream;
9 import java.io.IOException;
10 import java.io.InputStream;
11 import java.io.OutputStream;
12 import java.io.BufferedOutputStream;
13 import java.net.JarURLConnection;
14 import java.net.URL;
15 import java.util.Enumeration;
16 import java.util.jar.JarEntry;
17 import java.util.jar.JarFile;
18 import java.util.logging.Logger;
19
20 import uk.ac.roe.antigen.utils.CopyableFile;
21
22
23 /***
24 * Grabs a directory, or a zip file, and installs it in the temp directory for
25 * processing
26 *
27 * @author jdt
28 *
29 */
30 public class BuildGrabber {
31 /***
32 * Logger for this class
33 */
34 private static final Logger logger = Logger.getLogger(BuildGrabber.class.getName());
35
36
37 private CopyableFile tmpDir;
38
39 public static void main(String[] args) throws Exception {
40 BuildGrabber grabber = new BuildGrabber();
41 try {
42 CopyableFile tmp = grabber.tmpDir;
43 logger.fine("Temporary directory: " + tmp);
44
45 URL jarUrl = new URL(
46 "file:///C:/Documents and Settings/jdt/.maven/repository/org.astrogrid/wars/astrogrid-portal-0.7-b015p.war");
47
48 File copiedDir = grabber.grab("/foo");
49 logger.fine("Copied dir was " + copiedDir);
50 Thread.sleep(30000);
51 } finally {
52 System.out.println("Deleted? " + grabber.deleteTmp());
53 }
54 }
55
56 /***
57 * Source files are supplied as a known directory
58 *
59 * @param dir
60 * @throws IOException
61 * @return the tmp directory holding the files
62 */
63 public CopyableFile grab(File dir) throws IOException {
64 new CopyableFile(dir).copyTo(tmpDir);
65 return tmpDir;
66 }
67
68 /***
69 * Grabs contents of a jar file from a URL and unzip to a temp directory
70 *
71 * @param url
72 * of jar file
73 * @return the tmp directory holding the files
74 * @throws IOException
75 */
76 public CopyableFile grab(URL url) throws IOException {
77 String simpleUrl = url.toExternalForm();
78 logger.fine("Grabbing from " + simpleUrl);
79 JarURLConnection jarUrl = (JarURLConnection) new URL("jar:" + simpleUrl
80 + "!/").openConnection();
81 logger.fine("Opening connection to " + jarUrl);
82 JarFile jarFile = jarUrl.getJarFile();
83 return grab(jarFile);
84 }
85
86 /***
87 * Grab the contents of a jar file and unzip to a temp directory
88 *
89 * @param jar
90 * the jar file
91 * @return the tmp directory holding the files
92 * @throws IOException
93 * @TODO factor this out into separate class
94 */
95 public CopyableFile grab(JarFile jar) throws IOException {
96 Enumeration entries = jar.entries();
97 while (entries.hasMoreElements()) {
98 JarEntry entry = (JarEntry) entries.nextElement();
99 logger.fine("Entry " + entry);
100
101 File copiedFileEntry = new File(tmpDir, entry.getName());
102 logger.fine("Copying to " + copiedFileEntry.getAbsolutePath());
103
104 if (entry.isDirectory()) {
105 copiedFileEntry.mkdirs();
106 } else {
107 InputStream is = new BufferedInputStream(jar
108 .getInputStream(entry));
109 copiedFileEntry.createNewFile();
110 FileOutputStream os = new FileOutputStream(copiedFileEntry);
111
112 copyStreams(is, os);
113 }
114
115 }
116 return tmpDir;
117 }
118
119 private void copyStreams(InputStream in, OutputStream out)
120 throws IOException {
121 int data = -1;
122 while ((data = in.read()) != -1) {
123 out.write(data);
124 }
125 out.close();
126
127 in.close();
128 }
129
130 /***
131 * Grabs stuff off the classpath and stick it in the temp directory
132 *
133 * @param path
134 * the path off the classpath to the jar
135 * @return the temp directory in which the grabbed stuff has been stuck
136 * @throws IOException
137 */
138 public CopyableFile grab(String path) throws IOException {
139
140
141
142 if (path.startsWith("/")) {
143 path = path.substring(1);
144 }
145 File tmpJarFile = File.createTempFile("build", ".jar");
146 tmpJarFile.deleteOnExit();
147 JarFile installSource = new JarFile(System.getProperty("java.class.path"));
148 logger.fine("path: "+path);
149 File antBuildJar = unzipFile(path,installSource, tmpDir, false);
150
151 JarFile jar = new JarFile(antBuildJar);
152 unzipFile(null,jar,tmpDir,true);
153
154 return tmpDir;
155
156 }
157
158 /***
159 * Unzips either one file specified by fullPathFileName or all files (if fullPathFileName is null) from srcJar to destDir
160 * @param fullPathFileName
161 * @param srcJar
162 * @param destDir
163 * @return if fullPathFileName is not null then returns the unzipped file, otherwise returns null
164 */
165 private File unzipFile(String fullPathFileName, JarFile srcJar, File destDir, boolean useFullPath) {
166 int BUFFER = 16384;
167 BufferedOutputStream dest = null;
168 BufferedInputStream is = null;
169 JarEntry entry;
170 String newFullPathFileName = null;
171 Enumeration e = srcJar.entries();
172 try {
173 while(e.hasMoreElements()) {
174 entry = (JarEntry) e.nextElement();
175 if (fullPathFileName != null && !(entry.getName().equals(fullPathFileName) )) {
176 continue;
177 }
178
179 logger.fine("Extracting: " +entry);
180 is = new BufferedInputStream(srcJar.getInputStream(entry));
181 int count;
182 byte data[] = new byte[BUFFER];
183 int lastIndexOfSlashPlusOne = entry.getName().lastIndexOf('/')+1;
184 String path = null;
185 String fileName = null;
186 if (lastIndexOfSlashPlusOne == 0) {
187 path = "";
188 } else {
189 path = entry.getName().substring(0,lastIndexOfSlashPlusOne);
190 String sep = File.separator;
191 if (sep.equals("//")) {
192 sep = "////";
193 }
194 path = path.replaceAll("/",sep);
195 }
196 fileName = entry.getName().substring(lastIndexOfSlashPlusOne);
197 String newEntryName = destDir.getAbsolutePath()+File.separator+path+fileName;
198 if (!useFullPath) {
199 newEntryName = destDir.getAbsolutePath()+File.separator+fileName;
200 }
201 if (entry.isDirectory()) {
202 File entryFile = new File(newEntryName);
203 if (!entryFile.exists()) {
204 entryFile.mkdirs();
205 }
206 continue;
207 }
208 newFullPathFileName = newEntryName;
209
210 FileOutputStream fos = new FileOutputStream(newFullPathFileName);
211 dest = new
212 BufferedOutputStream(fos, BUFFER);
213 while ((count = is.read(data, 0, BUFFER)) != -1) {
214 dest.write(data, 0, count);
215 }
216 dest.flush();
217 dest.close();
218 is.close();
219 if (fullPathFileName != null) {
220 return new File(newFullPathFileName);
221 }
222 }
223 } catch(Exception ex) {
224 logger.warning(ex.getMessage());
225 ex.printStackTrace();
226 }
227
228 return null;
229 }
230
231 /***
232 * On the off chance that the system doesn't delete it, you can try to
233 * delete it yourself
234 *
235 * @return true or false depending on success
236 */
237 public boolean deleteTmp() {
238
239 return tmpDir.recursivelyDelete();
240 }
241
242 /***
243 * Set up temp directories etc
244 *
245 * @throws IOException
246 *
247 */
248 public BuildGrabber() throws IOException {
249 String systemTemp = System.getProperty("java.io.tmpdir");
250 logger.fine("System Temp Dir " + systemTemp);
251
252 tmpDir = new CopyableFile(File.createTempFile("antigen", "", new File(
253 systemTemp)));
254 logger.info("Build Dir " + tmpDir);
255
256 tmpDir.delete();
257 tmpDir.mkdirs();
258 tmpDir.deleteOnExit();
259 }
260 /***
261 * Set up temp directories etc
262 * User-supplied tmpdirectory
263 *
264 * @throws IOException
265 *
266 */
267 public BuildGrabber(File dir) throws IOException {
268 tmpDir = new CopyableFile(dir);
269 logger.info("Build Dir " + tmpDir);
270 }
271 }